iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0
Software Development

從像素到 Computer Vision:30 天理解數位影像處理系列 第 8

Day 8 | Kernel 設計:為什麼不同的 Kernel 會產生不同的效果?

  • 分享至 

  • xImage
  •  

昨天介紹了 Convolution,也認識了 Kernel。

我們知道,Convolution 的運算流程其實都一樣。

  1. 取出周圍的 Pixel。
  2. 和 Kernel 對應位置相乘。
  3. 全部加總。
  4. 得到新的 Pixel。

真正決定圖片效果的,其實是 Kernel

那麼問題來了,網路上常常可以看到各種不同的 Kernel。

例如:

1 1 1
1 1 1
1 1 1

或是:

0 -1  0
-1  5 -1
0 -1  0

它們到底是怎麼設計出來的?

總不可能大家都把這些矩陣背起來吧。

其實,大部分的 Kernel 設計,都可以從一個很簡單的問題開始思考。

希望圖片變成什麼樣子?

Kernel 本質上就是一組權重

昨天提到,Kernel 會和周圍 Pixel 一起運算。

但如果換個角度看,它其實就是一張「權重表」。

例如:

0 0 0
0 1 0
0 0 0

只有中心 Pixel 的權重是 1,其他位置都是 0。

這代表什麼?代表新的 Pixel 完全相信自己。

周圍 Pixel 完全沒有影響。

因此圖片最後會和原本一樣,不會有任何變化。

如果每個 Pixel 都一樣重要呢?

假設今天希望降低一些雜訊。

最直覺的方法,就是不要只看中心 Pixel,而是參考周圍的 Pixel。

例如:

1 1 1
1 1 1
1 1 1

九個位置的權重都一樣。

代表附近每個 Pixel 都有相同的重要性。

最後再把結果除以 9。

新的 Pixel 就會變成九個 Pixel 的平均值。

也因為如此,圖片會變得比較平滑。

這也是我們明天要討論的 Mean Filter

如果想讓圖片更銳利呢?

那是不是應該反過來?

不要平均大家。

而是讓中心 Pixel 更重要。

例如:

0 -1  0
-1  5 -1
0 -1  0

這個 Kernel 的中心權重最大。

周圍則是負值。

代表保留中心 Pixel 的資訊,同時減去部分周圍資訊。

因此邊緣會更加明顯,看起來就會有銳化的效果。

看到這邊,我們可以得到一個結論:不同的權重配置,就會產生不同的影像效果。

自己設計一個 Kernel 試試看

如果 Kernel 是一組權重。

那是不是代表,我們也可以自己設計?

例如:

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread("dog.jpeg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

先建立一個只有中心值的 Kernel。

kernel = np.array([
    [0,0,0],
    [0,1,0],
    [0,0,0]
], dtype=np.float32)

result = cv2.filter2D(img, -1, kernel)

結果會發現,圖片幾乎沒有任何改變。

接著,把中心值改成 2。

kernel = np.array([
    [0,0,0],
    [0,2,0],
    [0,0,0]
], dtype=np.float32)

result = cv2.filter2D(img, -1, kernel)

這次再觀察結果。

可以發現整張圖片變亮了。

因為每個 Pixel 都被乘上了 2。

如果再試著把中心值改成 0.5。

圖片又會變暗。

也就是說, Kernel 裡面的數字,本質上就是每個 Pixel 的權重。

Kernel 設計的三個觀念

看到這裡,我整理出三個覺得很重要的觀念。

1. 權重越大,代表越重要

數值越大,代表新的 Pixel 越受到該位置影響。

如果中心值最大,就表示比較相信中心 Pixel。

如果周圍值都差不多,就代表大家的重要性相近。

2. Kernel 越大,不代表越好

除了常見的 3×3。

還有:

  • 5×5
  • 7×7
  • 9×9

Kernel 越大,每次運算考慮的範圍越廣。

通常效果會更明顯,但同時也需要更多的計算時間。

因此 Kernel 大小通常是在效果與效率之間做取捨。

3. 權重總和會影響亮度

最後一個也是一開始最容易忽略的地方。

如果 Kernel 的總和是:

9

那新的 Pixel 通常會比原本亮。

如果總和是:

1

圖片的整體亮度通常會維持不變。

這也是為什麼 Mean Filter 會寫成:

1/9  1/9  1/9
1/9  1/9  1/9
1/9  1/9  1/9

而不是直接全部填 1。

因為這樣九個權重加起來剛好等於 1,可以避免整張圖片越來越亮。

今天總結

昨天介紹了 Convolution。

今天則試著回答另一個問題:

Kernel 為什麼會長這樣?

其實大部分的 Kernel,都不需要死背的矩陣。

它們只是根據想要達成的效果,去調整每個位置的權重。

理解這個概念之後,後面看到 Mean Filter、Gaussian Filter、Sharpen 或 Sobel 時,就不只是記住一個矩陣,而是知道它們為什麼會這樣設計。

明天,我們就從最簡單的一種開始。

Mean Filter(平均濾波器)。

看看「把周圍 Pixel 全部平均」這件事情,為什麼能夠讓圖片變得比較平滑。


上一篇
Day 7 | Convolution(卷積):為什麼影像處理幾乎都離不開它?
下一篇
Day 9 | Mean Filter:為什麼取平均,就能讓圖片變平滑?
系列文
從像素到 Computer Vision:30 天理解數位影像處理25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言